package cn.com.cifi.mars.util;

import cn.com.cifi.mars.constant.Constants;
import com.alibaba.druid.util.StringUtils;
import org.apache.poi.util.StringUtil;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * 类名称：LocalDateTimeUtils
 * 类描述：日期工具类 
 * 创建人：yyd 
 * 创建时间：2019年12月27日 下午6:19:47
 * @author Administrator
 *
 */
public class LocalDateTimeUtils {


	private static final String SDF ="yyyy-MM-dd HH:mm:ss";

	private static final String YEAR_MONTH_DAY="yyyy-MM-dd";

	private LocalDateTimeUtils() {

	}

	public static LocalDateTime convertDateToLDT(Date date) {
		return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
	}

	public static Date convertLDTToDate(LocalDateTime time) {
		return Date.from(time.atZone(ZoneId.systemDefault()).toInstant());
	}

	public static LocalDateTime parseDate(String dateStr, DateTimeFormatter dateTimeFormatter) {
		try {
			return LocalDateTime.of(LocalDate.parse(dateStr, dateTimeFormatter), LocalTime.MIN);
		} catch (Exception e) {
			return null;
		}
	}

	public static LocalDateTime strToDate(String dateStr, DateTimeFormatter dateTimeFormatter) {
		if(StringUtils.isEmpty(dateStr)){
			return null;
		}
		try {
			return LocalDateTime.parse(dateStr, dateTimeFormatter);
		} catch (Exception e) {
			return null;
		}
	}

	public static LocalDateTime strToLocalDateTime(String timeStr, String pattern) {
		if(StringUtils.isEmpty(timeStr)){
			return null;
		}
		try {
			DateTimeFormatter df = DateTimeFormatter.ofPattern(SDF);
			return LocalDateTime.parse(timeStr, df).minusMonths(1).with(TemporalAdjusters.lastDayOfMonth());
		} catch (Exception e) {
			return null;
		}
	}

	public static String formatTime(LocalDateTime time, String pattern) {
		if (null == time) {
			return null;
		}
		return time.format(DateTimeFormatter.ofPattern(pattern));
	}
	
	public static String formatDate(LocalDate time, String pattern) {
		if (null == time) {
			return null;
		}
		return time.format(DateTimeFormatter.ofPattern(pattern));
	}

	/**
	 * 上个月第一天
	 */
	public static LocalDateTime getFirstDayOfLastMonth() {
		LocalDateTime now = LocalDateTime.now();
		return now.minusMonths(1).with(TemporalAdjusters.firstDayOfMonth());
	}

	/**
	 * 上个月最后一天
	 */
	public static LocalDateTime getLastDayOfLastMonth() {
		LocalDateTime now = LocalDateTime.now();
		return now.minusMonths(1).with(TemporalAdjusters.lastDayOfMonth());
	}

	/**
	 * 上个月最后一天
	 */
	public static LocalDateTime getLastDayOfLastMonth(LocalDateTime localDateTime) {
		LocalDateTime now = localDateTime;
		return now.minusMonths(1).with(TemporalAdjusters.lastDayOfMonth());
	}
	/**
	 *
	 * @Description：上个月份
	 */

	public static String getLastMonth(String yearMonth) {
		String time = yearMonth + "-01 00:00:00";
		DateTimeFormatter df = DateTimeFormatter.ofPattern(SDF);
		LocalDateTime date = LocalDateTime.parse(time, df).minusMonths(1).with(TemporalAdjusters.lastDayOfMonth());
		return LocalDateTimeUtils.formatTime(date,DateUtils.DATE_JFP_STR);
	}

	/**
	 *
	 * @Description：下个月份
	 */
	public static String getNextMonth(String yearMonth) {
		String time = yearMonth + "-01 00:00:00";
		DateTimeFormatter df = DateTimeFormatter.ofPattern(SDF);
		LocalDateTime date = LocalDateTime.parse(time, df).plusMonths(1).with(TemporalAdjusters.lastDayOfMonth());
		return LocalDateTimeUtils.formatTime(date,DateUtils.DATE_JFP_STR);
	}
	
	public static String getEndConfirmDate(String yearMonth) {
		String time = yearMonth + Constants.CONFIRM_END_TIME;
		DateTimeFormatter df = DateTimeFormatter.ofPattern(SDF);
		LocalDateTime date = LocalDateTime.parse(time, df).plusMonths(1).with(TemporalAdjusters.firstDayOfMonth());
		return LocalDateTimeUtils.formatTime(date,DateUtils.DATE_FULL_STR);
	}

	public static LocalDateTime getBeginTime(int year, int month) {
		YearMonth yearMonth = YearMonth.of(year, month);
		LocalDate localDate = yearMonth.atDay(1);
		return localDate.atStartOfDay();
	}

	public static LocalDateTime getEndTime(int year, int month) {
		YearMonth yearMonth = YearMonth.of(year, month);
		LocalDate endOfMonth = yearMonth.atEndOfMonth();
		return endOfMonth.atTime(23, 59, 59, 999);
	}

	public static boolean isBetweenTwoMonth(int beginMonth, int endMonth, int curMonth) {
		return curMonth >= beginMonth && curMonth <= endMonth;
	}

	/**
	 * 日期向上递增一个月
	 */
	public static LocalDateTime addDate(LocalDateTime time) {
		return time.plusMonths(1);
	}

	/**
	 * type=0:判断日期年月是否小于指定日期年月
	 * type=1:判断日期年月是否小于等于指定日期年月
	 * type=2:判断日期年月是否等于指定日期年月
	 */
	public static boolean compareDate(LocalDateTime timeA, LocalDateTime timeB, int type) {
		int a = Integer.valueOf(timeA.toLocalDate().toString().substring(0, 7).replace("-",""));
		int b = Integer.valueOf(timeB.toLocalDate().toString().substring(0, 7).replace("-",""));

		if(type == Constants.ZERO){
			return a < b;
		}else if(type ==Constants.ONE){
			if (a <= b) {
				return true;
			}
		}else if(type ==Constants.TWO){
			return a == b;
		}
		return false;
	}

	/**
	 * 获取一年最后一个月的日期
	 */
	public static LocalDateTime getLatestMonthDate(LocalDateTime localDateTime) {
		String time = localDateTime.getYear() + "-12-31 23:59:59";
		DateTimeFormatter df = DateTimeFormatter.ofPattern(SDF);
		return LocalDateTime.parse(time, df);
	}


	/**
	 * 获取一年第一个天的日期
	 */
	public static LocalDateTime getEarliestMonthDate(LocalDateTime localDateTime) {
		String time = localDateTime.getYear() + "-01-01 00:00:00";
		DateTimeFormatter df = DateTimeFormatter.ofPattern(SDF);
		return LocalDateTime.parse(time, df);
	}

	/**
	 * 获取一年第一个月的一天的日期
	 */
	public static LocalDateTime getEarliestMonthDate(String year) {
		String time = year + "-01-01 00:00:00";
		DateTimeFormatter df = DateTimeFormatter.ofPattern(SDF);
		return LocalDateTime.parse(time, df);
	}

	public static LocalDateTime toLocalDateTime(String yearMonth) {
		String time = yearMonth + "-01 00:00:00";
		DateTimeFormatter df = DateTimeFormatter.ofPattern(SDF);
		return LocalDateTime.parse(time, df);
	}

	/**
	 * 拼接年月份
	 * @param a 年份
	 * @param b 月份
	 * @return
	 */
	public static int toIntYearMonth(Integer a, Integer b) {
		String year;
		String month;
		if (b.toString().length() == 1) {
			month = "0" + b.toString();
		} else {
			month = b.toString();
		}
		year = a.toString();
		return Integer.valueOf(year + month);
	}

	/**
	 * 年月份
	 * @return
	 */
	public static int toIntYearMonth(LocalDateTime time) {

		return Integer.valueOf(formatTime(time, "yyyyMM"));
	}

	/**
	 * 拼接年月份
	 *
	 * @param a
	 *            年份
	 * @param b
	 *            月份
	 * @return
	 */
	public static String toStrYearMonth(Integer a, Integer b) {
		String year;
		String month;
		if (b.toString().length() == 1) {
			month = "0" + b.toString();
		} else {
			month = b.toString();
		}
		year = a.toString();
		return String.valueOf(year + "-" + month);
	}

	public static String getConfirmTime(String endSuffix) {
		String confirmTime = "";
		DateTimeFormatter df = DateTimeFormatter.ofPattern(SDF);
		LocalDateTime now = LocalDateTime.now();
		if(is0And6(endSuffix)) {
			LocalDateTime confirmDate = strToDate(formatTime(now,"yyyy-MM")+endSuffix,df);
			confirmTime = formatTime(confirmDate,SDF);
		}else {
			LocalDateTime lastDayOfMonth = getLastDayOfTheMonth(LocalDateTime.now());
			LocalDateTime confirmDate = strToDate(formatTime(addDate(lastDayOfMonth),"yyyy-MM")+endSuffix,df);
			confirmTime = formatTime(confirmDate,SDF);
		}
		return confirmTime;
	}

	public static boolean is0And6(String endSuffix){
		LocalDateTime now = LocalDateTime.now();
		String yearMonth = getLocalMonth(now);
		DateTimeFormatter df = DateTimeFormatter.ofPattern(SDF);
		String begin = yearMonth + "-01 00:00:00";
		String end = yearMonth + endSuffix;
		LocalDateTime beginTime = LocalDateTime.parse(begin, df);
		LocalDateTime endTime = LocalDateTime.parse(end, df);
		return now != null && now.isAfter(beginTime) && now.isBefore(endTime);
	}

	public static boolean isConfirmTime(String defaultConfirmTime,String startSuffix) {
		if(StrUtils.isEmpty(startSuffix)) {
			startSuffix = Constants.CONFIRM_START_TIME;
		}
		DateTimeFormatter df = DateTimeFormatter.ofPattern(SDF);
		LocalDateTime now = LocalDateTime.now();
		LocalDateTime confirmTime = LocalDateTime.parse(defaultConfirmTime, df);
		LocalDateTime tempTime = null;
		if(now.getMonthValue() != confirmTime.getMonthValue()) {
			tempTime = lastTwoDayOfMonth(startSuffix);
		}else {
			tempTime = lastTwoDayOfLastMonth(startSuffix);
		}
		return now.isBefore(confirmTime) && now.isAfter(tempTime);
	}

	public static List<String> getSupplyConfirmDetailMonths(int year, int month) {
		List<String> months = Collections.synchronizedList(new ArrayList<>());
		if (month == Constants.TWELVE) {
			year = year + 1;
			for (int i = 1; i <= Constants.TWELVE; i++) {
				if (i < 10) {
					months.add(year + "-" + "0" + i);
				} else {
					months.add(year + "-" + i);
				}
			}
		} else {
			for (int i = month + 1; i <= Constants.TWELVE; i++) {
				if (i < 10) {
					months.add(year + "-" + "0" + i);
				} else {
					months.add(year + "-" + i);
				}
			}
		}
		return months;
	}

	/**
	 * 获取yyyy-mm
	 *
	 * @return
	 */
	public static String getLocalMonth(LocalDateTime time) {
		if (null == time) {
			return null;
		}
		return formatTime(time,"yyyy-MM");
	}


	/**
	 * 获取当前年第一个月yyyy-mm
	 *
	 * @return
	 */
	public static String getLocalFirstMonth(String year) {
		return year + "-01";
	}


	/**
	 *
	 * 方法描述：上个月底前两天
	 */
	public static LocalDateTime lastTwoDayOfLastMonth(String startSuffix) {
		LocalDateTime lastDate =  LocalDateTime.now().minusMonths(1).with(TemporalAdjusters.lastDayOfMonth());
		String time = formatTime(lastDate, YEAR_MONTH_DAY)+" "+startSuffix;
		LocalDateTime date = parseDate(time, DateTimeFormatter.ofPattern(SDF));
		if(date!=null) {
			return date.with(TemporalAdjusters.lastDayOfMonth()).minusDays(1);
		}
		return date;
	}

	/**
	 *
	 * 方法描述：当前月底前两天
	 */
	public static LocalDateTime lastTwoDayOfMonth(String startSuffix) {
		String time = formatTime(LocalDateTime.now(), YEAR_MONTH_DAY)+" "+startSuffix;
		LocalDateTime date = parseDate(time, DateTimeFormatter.ofPattern(SDF));
		if(date!=null) {
			return date.with(TemporalAdjusters.lastDayOfMonth()).minusDays(1);
		}
		return date;
	}


	/**
	 * 当月最后一天
	 */
	public static LocalDateTime getLastDayOfTheMonth(LocalDateTime time) {
		LocalDateTime end = time.with(TemporalAdjusters.lastDayOfMonth());
		return getEndTime(end.getYear(),end.getMonthValue());
	}


	/**
	 * 获取当前时间 yyyy-mm-dd hh:mm:ss
	 *
	 * @return
	 */
	public static String getLocalTime() {
		LocalDateTime now = LocalDateTime.now();
		String localDate = now.toLocalDate().toString();
		String time = now.toLocalTime().toString();
		return localDate + " " + time.split("\\.")[0];
	}
	
	/**
	 * 判断当前时间是否是在1号0点-6点之间
	 * @return
	 */
	public static boolean isBetween0And6(){
		LocalDateTime now = LocalDateTime.now();
		String yearMonth = LocalDateTimeUtils.getLocalMonth(now);
		DateTimeFormatter df = DateTimeFormatter.ofPattern(SDF);
		String s1 = yearMonth + "-01 00:00:00";
		String s2 = yearMonth + "-01 06:00:00";
		LocalDateTime time1 = LocalDateTime.parse(s1, df);
		LocalDateTime time2 = LocalDateTime.parse(s2, df);
		if(now!=null) {
			return (
						// 大于等于
						now.compareTo(time1) == 0  || now.isAfter(time1)
					)
					&&
					(
						// 小于等于
						now.compareTo(time2) == 0  || now.isBefore(time2)
					);
		}
		return false;
	}

	/**
	 *  根据日期 转换成 yyyy-mm-dd 时:分:秒
	 * @param now
	 * @return
	 */
	public static String getTimeTransformStr(LocalDateTime now) {
		String localDate = now.toLocalDate().toString();
		String time = now.toLocalTime().toString();
		return localDate + " " + time.split("\\.")[0];
	}

	/**
	 * 解析 2020-01-01T15:24:17.000+0800 为LocalDateTime
	 * @param createdTime
	 * @return
	 */
	public static LocalDateTime analysisDate(String createdTime) {
		String timeStr=createdTime.substring(0,19).replace("T", " ");
		DateTimeFormatter df = DateTimeFormatter.ofPattern(SDF);
		return LocalDateTime.parse(timeStr,df);
	}

	/**
	 * 将timestamp转为LocalDateTime
	 * @param timestamp 1559318400000
	 * @return
	 */
	public static LocalDateTime timestamToDatetime(String timestamp){
		Instant instant = Instant.ofEpochMilli(Long.parseLong(timestamp));
		return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
	}

	public static boolean isSameMonth(String defultMonth) {
		String now = LocalDateTimeUtils.formatTime(LocalDateTime.now(),DateUtils.DATE_JFP_STR);
		if(StrUtils.isEmpty(now)) {
			return false;
		}
		return defultMonth.equals(now);
	}

	/**
	 * 转年月整型
	 * @return
	 */
	public static int toIntYM(LocalDateTime time) {
		String year;
		String month;
		if (String.valueOf(time.getMonthValue()).length() == 1) {
			month = "0" + time.getMonthValue();
		} else {
			month = String.valueOf(time.getMonthValue());
		}
		year = String.valueOf(time.getYear());
		return Integer.valueOf(year + month);
	}
	
	public static long diffTime(LocalDateTime targetTime) {
		LocalDateTime now = LocalDateTime.now();
		Duration duration = Duration.between(targetTime,now);
		return duration.toHours();
	}
	
	public static boolean isValidTime(LocalDateTime targetTime,int hour) {
		long hours = diffTime(targetTime);
		return hours < hour;
	}

	/**
	 * 获取两个时间点的月份差
	 * @param dt1 第一个时间点
	 * @param dt2 第二个时间点
	 * @return int，即需求的月数差
	 */
	public static int monthDiff(LocalDateTime dt1,LocalDateTime dt2){
		//获取第一个时间点的月份
		int month1 = dt1.getMonthValue();
		//获取第一个时间点的年份
		int year1 = dt1.getYear();
		//获取第一个时间点的月份
		int month2 = dt2.getMonthValue();
		//获取第一个时间点的年份
		int year2 = dt2.getYear();
		//返回两个时间点的月数差
		return (year2 - year1) *12 + (month2 - month1);
	}

	/**
	 * 获取两个时间点的月份差
	 * @param dt1 第一个时间点
	 * @param dt2 第二个时间点
	 * @return int，即需求的月数差
	 */
	public static int monthDiff_two(LocalDateTime dt1,LocalDateTime dt2){
        //获取第一个时间点的月份
        int day1 = dt1.getDayOfMonth();
		//获取第一个时间点的月份
		int month1 = dt1.getMonthValue();
		//获取第一个时间点的年份
		int year1 = dt1.getYear();
		//获取第一个时间点的月份
		int month2 = dt2.getMonthValue();
		//获取第一个时间点的年份
		int year2 = dt2.getYear();
        //获取第二个时间点的月份
        int day2 = dt2.getDayOfMonth();

        //返回两个时间点的月数差
		int diff = (year2 - year1) *12 + (month2 - month1);
        if(day2 < day1){
            diff = diff - 1;
        }
        return diff;
	}


	/**
	 * 比较两个年月大小
	 * -1 小于
	 * 0 等于
	 * 1 大于
	 * @param yearMontA yyyy-mm
	 * @param yearMonthB yyyy-mm
	 * @return
	 */
	public static int compareYearMonth(String yearMontA, String yearMonthB) {
		String[] splitA = yearMontA.split("-");
		String[] splitB = yearMonthB.split("-");

		int yearA = Integer.parseInt(splitA[0]);
		int monthA = Integer.parseInt(splitA[1]);
		int yearB = Integer.parseInt(splitB[0]);
		int monthB = Integer.parseInt(splitB[1]);

		int compare = Integer.compare(yearA, yearB);
		if(compare == 0){
			compare = Integer.compare(monthA, monthB);
		}
		return compare;
	}
	
	public static String getLastByFormat(int day,String timeFormat){
		return LocalDateTime.now().minusDays(day).format(DateTimeFormatter.ofPattern(timeFormat));
	}

}
